#include "stdint.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define GPIO_EXPORT_PATH "/sys/class/gpio/export"
#define GPIO_UNEXPORT_PATH "/sys/class/gpio/unexport"
#define GPIO_DIRECTION_PATH "/sys/class/gpio/gpio%d/direction"
#define GPIO_VALUE_PATH "/sys/class/gpio/gpio%d/value"

void gpio_set_direction(const uint8_t pin, const uint8_t direction) {
    char path[100];
    snprintf(path, sizeof(path), GPIO_DIRECTION_PATH, pin);

    FILE *fd = fopen(path, "w");
    if (fd == NULL) {
        perror("Error opening GPIO direction file");
        exit(1);
    }
    char dirstr[3];
    if(direction == 1){
        fprintf(fd,  "in");
    }else {
        fprintf(fd,  "out");
    }
    fflush(fd);
    fclose(fd);
}

void gpio_set_level(const uint8_t pin, int value) {
    char path[100];
    snprintf(path, sizeof(path), GPIO_VALUE_PATH, pin);

    FILE *fd = fopen(path, "w");
    if (fd == NULL) {
        perror("Error opening GPIO value file");
        exit(1);
    }

    if (value == 0) {
        fprintf(fd,  "0");
    } else {
        fprintf(fd,  "1");
    }
    fflush(fd);
    fclose(fd);
}

int gpio_init(const uint8_t pin) {
    int pin_export_fd = open(GPIO_EXPORT_PATH, O_WRONLY);
    if (pin_export_fd < 0) {
        perror("Error opening GPIO export file");
        return 1;
    }

    char pin_name[3];
    snprintf(pin_name, sizeof(pin_name), "%d", pin);
    write(pin_export_fd, pin_name, strlen(pin_name));
    close(pin_export_fd);

    gpio_set_direction(pin, 1); // 设置 GPIO 引脚为输出模式

    return 0;
}

int gpio_deinit(const uint8_t pin) {
    int pin_unexport_fd = open(GPIO_UNEXPORT_PATH, O_WRONLY);
    if (pin_unexport_fd < 0) {
        perror("Error opening GPIO unexport file");
        return 1;
    }

    char pin_name[3];
    snprintf(pin_name, sizeof(pin_name), "%d", pin);
    write(pin_unexport_fd, pin_name, strlen(pin_name));
    close(pin_unexport_fd);

    return 0;
}